package component{
    import component.entry.*;
    
    import flash.display.DisplayObject;
    import flash.events.*;
    import flash.ui.ContextMenu;
    import flash.ui.ContextMenuItem;
    
    import flexlib.containers.SuperTabNavigator;
    
    import mx.containers.*;
    import mx.controls.*;
    import mx.core.Repeater;
    import mx.core.WindowedApplication;
    import mx.events.FlexEvent;
    import mx.managers.PopUpManager;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.http.HTTPService;
    
    import org.pubflex.AssetManager;
    import org.pubflex.Keybindings;
    
	public class BrowserBarBase extends VBox{
            namespace XML_NS = "http://www.w3.org/XML/1998/namespace";
            namespace ATOM = "http://www.w3.org/2005/Atom"
            namespace APP = "http://www.w3.org/2007/app";
            namespace ATOM_PURL = "http://purl.org/atom/ns#";
            	
			[Bindable] public var catChoice:Array = new Array();          
		    [Bindable] public static var baseURI:String;                 
            [Bindable] public var serviceFeed:XML;            
            [Bindable] public var serviceDocument:XML;
            [Bindable] public var serviceDocumentList:XMLList;
			[Bindable] public var feedDocument:XML;
			[Bindable] public var menu:ContextMenu = new ContextMenu();
			//[Bindable] public var workspacePanel:TitleWindow;
			[Bindable] public var entryPanel:EntryPod; 
            [Bindable] public var workspaceRepeater:Repeater;    
        
			public var atomPubService:HTTPService;
			public var feedFetchService:HTTPService
			public var collectionPanel:VBox;
			public var feedPanel:FeedPanel;

			public var urlInput:ComboBox; 
			public var newEntryMenuItem:ContextMenuItem;			
			public var collectionRepeater:Repeater; 
			public var currentEntry:XML;
			public var currentCollection:XML;
            public var keybindings:Keybindings = new Keybindings();    		    		

		public function BrowserBarBase(){
			super();									    		
			initMenus();
            initAtomPubService();	
            keybindings.addEventListener(NewEntryBase.POST_COMPLETE, handlePostComplete);
            //keybindings.addEventListener(MouseEvent.CLICK, handlePostComplete, true);
            
            trace(keybindings.hasEventListener(NewEntryBase.POST_COMPLETE));

            
		}
		
		public function handleKeys(e:KeyboardEvent):void{            

            keybindings.handleKeyEvent(e, this);
                        
            //entryForm.addEventListener(EntryFormBase.DELETE_COMPLETE,handleDeleteComplete);
		}
		
		public function handlePostComplete(e:Event):void{
		    trace("Bubbles are cool");
            // Reload the FeedPanel now that we've added an entry to the feed
            if(feedFetchService.url != null){
		        feedFetchService.send();
                WindowedApplication(parent).status = "fetching " + feedFetchService.url;
            }
		}
		

		
		public function autoLoad():void{
            if(urlInput.dataProvider == null){
                return;
            }     
             atomPubService.url = urlInput.dataProvider[0]; 
             atomPubService.send(); 
            this.addEventListener(KeyboardEvent.KEY_DOWN, handleKeys)
                
		}
		
		private function initMenus():void{
    		menu.hideBuiltInItems();
    		//menu.addEventListener(Event.ACTIVATE, handleNewEntryMenuEvent);
    		            
			newEntryMenuItem = new ContextMenuItem('New Entry');
			newEntryMenuItem.enabled = true;
			//newEntryMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handleNewEntryMenuEvent);
    		menu.customItems.push(newEntryMenuItem);    		    		    		
			contextMenu = menu;
		}
		
		private function initAtomPubService():void{
            atomPubService = new HTTPService(); 		    
		    atomPubService.useProxy = false; 
		    atomPubService.resultFormat = "e4x";
            atomPubService.addEventListener(ResultEvent.RESULT, handleServiceRequest);
            atomPubService.addEventListener(FaultEvent.FAULT, handleRequestFault);		
        
            feedFetchService = new HTTPService();
           	feedFetchService.useProxy = false;
       		feedFetchService.resultFormat = "e4x";
            feedFetchService.addEventListener(ResultEvent.RESULT, handleFeedRequest);
            feedFetchService.addEventListener(FaultEvent.FAULT, handleRequestFault);
		}
		
		public function handleNewEntryMenuEvent(e:Event):void{
		    trace("Help Me");

    		trace("Post a new entry to collection :" + e.target);	
                var myParent:DisplayObject = this.parentApplication as DisplayObject; 
                var viewer:XmlViewer = XmlViewer(PopUpManager.createPopUp(myParent, XmlViewer , true));
				//var viewer:XmlViewer = XmlViewer(PopUpManager.createPopUp( this, XmlViewer , true));
				
				
				viewer.xmlText.text = "Boy! There's a lot to do.";
				mx.managers.PopUpManager.centerPopUp(viewer);		
		}
				
        public function parserAndStoreBaseUri(url:String):void{
            trace("trying to parse base uri from " + url);
            var pattern:RegExp = /(.*)\/;service_document/;
            var result:Object = pattern.exec(url);
            if(result != null){                 
                trace("REGEX " + result[1]);
                BrowserBarBase.baseURI = result[1];
                return;                    
            }                 
             BrowserBarBase.baseURI =  serviceDocument.@base;                                 
        }

        public function handleServiceRequest(event:ResultEvent):void {            	
            	trace("serviceResultHandler(event) Called ");
            	trace("Using URL " + atomPubService.url);
                use namespace ATOM;
                use namespace APP;                
                use namespace XML_NS;                

                var xml:XML = event.result as XML;

                // See if we happen to have fetched a feed doc instead of a service doc. 
                
                var qName:QName = xml.name();
                if(qName != null && qName.localName == "feed"){
                    trace("This is actually a feed and not a service");
                    trace ( qName.localName ); 
                    handleFeedRequest(event);
                    return;
                    
                }
                                    	            	            				
				serviceDocument = xml
                
                
                parserAndStoreBaseUri(atomPubService.url);
                
                if(feedPanel != null){
    				feedPanel.entriesRepeater.dataProvider = null;
                }
				serviceDocumentList = serviceDocument.APP::workspace;

                workspaceRepeater.addEventListener(FlexEvent.REPEAT_START,setF);
				workspaceRepeater.initialize();

				trace(serviceDocument);
				trace(serviceDocument.APP::workspace);
				trace("workspaces :" + serviceDocumentList);

        }
        
        public function setF(e:Event):void{
            trace("****************************************");
        }
        
            
        public function handleFeedRequest(event:ResultEvent):void {            	
            	trace("feedResultHandler(event) called" );
            
				feedDocument = event.result as XML;				
				if(feedDocument == null){
				    return;
				}								            

                use namespace XML_NS;        
                use namespace ATOM;        
                use namespace ATOM_PURL;        
                var entries:XMLList = feedDocument.entry; 
                var entry:XML;
                //var linkArray:Array = new Array();
                for each(entry in entries){
                     entry.addNamespace(XML_NS);
                     entry.addNamespace(APP);
                     entry.@XML_NS::base = feedDocument.@XML_NS::base;
                     trace(entry);
                     //var link:Label = new Label();
                     //link.data = entry; 
                     //link.label = "--" + entry.title;
                     //link.ti = "--" + entry.title;
                     //linkArray.push(link);
                }

				feedPanel.entriesRepeater.dataProvider = entries;

				//feedPanel.title = "Feed : Total - " + feedDocument.children().length();
				
				trace(	feedPanel.entriesRepeater);
                
                feedPanel.header.headerTitle = "FEED : Count - " + entries.length();                
                feedPanel.entriesRepeater.dispatchEvent(event);
                
                feedPanel.entriesRepeater.addEventListener(MouseEvent.CLICK, handleViewEntryEvent, true, 0);
                feedPanel.addEventListener(MouseEvent.CLICK, handleViewEntryEvent, true, 0);                
                
                WindowedApplication(parent).status = "Last Fetch :  " + feedFetchService.url;
            }
                  
            public function handleEntryChange(event:HTTPStatusEvent):void{
                   var status:int = event.status;   
                   feedFetchService.send();
            }                 
            
            public function viewFeed(e:Event):void{	
				trace("viewFeed(event)");				
				var xml:XML = e.currentTarget.data;	                
                currentCollection = xml;            				
				            
				feedFetchService.url = buildLink(xml.@href);
								 				
				if(feedFetchService.url == null){
					Alert.show("Using URL " + urlInput.text, "Could not dereference Feed");
					return;			
				}
			
				trace("URL :" + feedFetchService.url);
				feedFetchService.send();
            }
                       
            private function buildLink(resourcePath:String):String{
                trace("buildLink() " );
                
            	use namespace XML_NS;
                var baseURL:String = serviceDocument.@base; 
                trace(serviceDocument);                
                trace(serviceDocument.namespaceDeclarations());                
                trace("Base : " + baseURL);
                
                if(baseURL !== "" && baseURL !== null){
                    trace(baseURL);
                    return baseURL + "/" + resourcePath;
                }

                 if( resourcePath.search("http") > -1){
                    trace("Collection link will be : " + resourcePath );
                    return resourcePath;
                }                               
                else{
                    trace("Collection link will be : " +  BrowserBarBase.baseURI + "/" + resourcePath );
                    return baseURI + "/" + resourcePath;    
                }                            
            }               
            
            public function fetchService(oEvent:Object):void{    
                if(feedPanel != null) {      
                	feedPanel.entriesRepeater.dataProvider = null;
                }
            	
            	if(collectionPanel != null){
            	    collectionPanel.removeAllChildren();
            	}
            	
                if(collectionRepeater != null){
            	    collectionRepeater.dataProvider = null;
                }

            	atomPubService.url = urlInput.text;
				atomPubService.send();
            }    
                        
			public function viewSource(e:MouseEvent):void {

               var myParent:DisplayObject = this.parentApplication as DisplayObject; 
                trace(myParent);
                
                //var myPopUp:formComponent = MailToFriendForm(PopUpManager.createPopUp(myParent, formComponent, true));
   										
				var viewer:XmlViewer = XmlViewer(PopUpManager.createPopUp(myParent, XmlViewer , true));
				//var viewer:XmlViewer = XmlViewer(PopUpManager.createPopUp( this, XmlViewer , true));
				
				if(serviceDocument == null){
				   viewer.xmlText.text = "You must first fetch an AtomPub ServiceDocument.";
				}else{
   					viewer.xmlText.text = serviceDocument.toXMLString();
				}					
				
				mx.managers.PopUpManager.centerPopUp(viewer);									   			
   			}  
   			

   			
   			// XXX This should probably be move into the a Feed / Entry 
   			//     specific class
   			public function handleViewEntryEvent(e:Event):void{
       			 if(e.target is IsmLinkButton){       			            			     
       			 	var entryLink:IsmLinkButton = e.target as IsmLinkButton;
       			 	trace(entryLink.entryXML);
                    currentEntry = entryLink.entryXML as XML;       			 	       			 	                           			 	                             			    
       			 }       

                use namespace ATOM;
                use namespace ATOM_PURL; 
                
                if(currentEntry != null){
                    var name:String = currentEntry.id
                    var child:Object = entryPanel.entryTabNavigator.getChildByName(name);
                    if(child != null){
                        return;
                    }
                }
                    
                var entryForm:EntryForm = new EntryForm();
                //entryForm.getLabel()
                
                var v:VBox = new VBox(); 
                v.label = "Entry";
                v.addChild(entryForm);
                v.icon = AssetManager.ICON_FEED_10X10;                            
                v.name = currentEntry.id;    
                trace(currentEntry.id);
                entryPanel.entryTabNavigator.addChild(v);
                                 
                entryForm.loadXml(currentEntry, currentCollection);
                // Make the last tab active
                entryPanel.entryTabNavigator.selectedIndex = entryPanel.entryTabNavigator.getChildren().length-1;
                entryForm.addEventListener(EntryFormBase.DELETE_COMPLETE,handleDeleteComplete);

   			}
   	   			
    public function handleDeleteComplete(e:Event):void{
        trace(e);
        trace("from here we need to remove the entry and the label from the tabNavigator");
                      
        var etp:SuperTabNavigator = entryPanel.entryTabNavigator;
        trace( etp.instanceIndex ); 
        trace( etp.selectedIndex);
        etp.removeChildAt(  etp.selectedIndex ) ;
        feedFetchService.send();
        
    }   	   			
    public function traceEvent(e:Event):void{
            trace(e);
            trace(e.currentTarget);
            trace(e.target);            
        }   	   			
   			            
            public function handleRequestFault(event:FaultEvent):void{
                Alert.show("Using URL " + urlInput.text, "Could not dereference APP Service Document");
            }
                                    
            public function handleViewFeedEvent(e:Event):void{
                trace(e);
            }
            
            public function viewCollection(xml:XML):void{
                if(feedPanel != null){
                    feedPanel.entriesRepeater.dataProvider = null;             	          		
                }
                
                collectionPanel.removeAllChildren();
					            	   		    		
            	catChoice = new Array();        	
            	var colXml:XMLList = xml.APP::collection;
	            trace(colXml);
	
	            var item:XML;
	            for each(item in colXml) {
    	            trace("item: " + item.toXMLString());

                    var hBox:HBox = new HBox(); 
                    

    	        	var collectionButton:LinkButton = new LinkButton();

    	        	collectionButton.label = item.ATOM::title;
    	        	trace(collectionButton.label);
    	        	collectionButton.data = item;

    	        	collectionButton.doubleClickEnabled = true;
    	        	collectionButton.addEventListener(MouseEvent.DOUBLE_CLICK, handleNewEntryMenuEvent);
    	        	collectionButton.addEventListener(MouseEvent.CLICK, viewFeed);
    	        	
                    trace(collectionButton.data);
					collectionButton.toolTip = item;
					collectionButton.id = item.APP::title;
                    collectionButton.styleName = "LinkButton";
    	        	catChoice.push(collectionButton);


                    var l:Label = new Label();
                    l.text = "Foo";
                    
                    var image:Image = new Image();
                    image.source = AssetManager.ICON_BRICK_ADD;
                    image.buttonMode = true;
                    image.mouseChildren = true; 
                    image.addEventListener(MouseEvent.CLICK , handleNewEntryMenuEvent);
                    
    	        	//collectionPanel.addChild(collectionButton);
                    hBox.addChild(image);
                    hBox.addChild(collectionButton);

                    
    	        	collectionPanel.addChild(hBox);
        	    }
            }             		
    }
}